package com.gf.framework.mongo.lambda;

import com.baomidou.mybatisplus.core.toolkit.LambdaUtils;
import com.baomidou.mybatisplus.core.toolkit.support.LambdaMeta;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import org.apache.ibatis.reflection.property.PropertyNamer;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author gaofei
 * @date 2022/5/29 11:20
 */
public class MongoLambdaColumn {
    private static Map<Object, String> lambdaMetaMap = new ConcurrentHashMap<>();

    private List<String> columns;
    private Integer index;
    private MongoLambdaColumn() {
        columns = new ArrayList<>();
    }


    public static MongoLambdaColumn create() {
        return new MongoLambdaColumn();
    }

    public <T> MongoLambdaColumn builder(SFunction<T, Object> sFunction) {
        columns.add(getFieldName(sFunction));
        return this;
    }

    /**
     * 数组坐标构建
     * @param index
     * @param <T>
     * @return
     */
    public <T> MongoLambdaColumn builder(int index) {
        columns.add(String.valueOf(index));
        return this;
    }

    public String getFieldName() {
        if (columns.isEmpty()) {
            return null;
        }
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < columns.size(); i++) {
            stringBuilder.append(columns.get(i));
            if (columns.size() - 1 != i) {
                stringBuilder.append(".");
            }
        }
        return stringBuilder.toString();
    }

    private  <T> String getFieldName(SFunction<T, Object> column) {
        if (lambdaMetaMap.containsKey(column)) {
            return lambdaMetaMap.get(column);
        }
        LambdaMeta meta = LambdaUtils.extract(column);
        String fieldName = PropertyNamer.methodToProperty(meta.getImplMethodName());
        lambdaMetaMap.put(column, fieldName);
        return fieldName;
    }
}
